#!/usr/bin/env bun

/**
 * 浏览器调试 MCP 工具
 *
 * 提供非headless浏览器控制功能，支持网页调试
 * 包括：启动、截图、页面信息获取、脚本执行等
 */

import fs from 'fs/promises';
import { createChildLogger } from '../../utils/logger.js';
import {
  getBrowserManager,
  type BrowserContextConfig,
  type ScreenshotOptions,
} from './browser-manager.js';

const logger = createChildLogger('BrowserDebugTools');

/**
 * 统一响应格式
 */
interface BaseResponse {
  success: boolean;
  message: string;
  timestamp: string;
}

interface SuccessResponse<T = any> extends BaseResponse {
  success: true;
  data: T;
}

interface ErrorResponse extends BaseResponse {
  success: false;
  error: string;
}

type BrowserResponse<T = any> = SuccessResponse<T> | ErrorResponse;

/**
 * 创建成功响应
 */
function createSuccessResponse<T>(
  data: T,
  message: string = 'Operation completed successfully'
): SuccessResponse<T> {
  return {
    success: true,
    message,
    data,
    timestamp: new Date().toISOString(),
  };
}

/**
 * 创建错误响应
 */
function createErrorResponse(error: unknown, message: string = 'Operation failed'): ErrorResponse {
  const errorMessage = error instanceof Error ? error.message : String(error);
  logger.error(message, { error: errorMessage });

  return {
    success: false,
    message,
    error: errorMessage,
    timestamp: new Date().toISOString(),
  };
}

/**
 * 启动浏览器调试服务
 */
export async function startBrowserDebug(input: {
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
  mode?: 'headed' | 'headless';
  devtools?: boolean;
  maximized?: boolean;
}): Promise<
  BrowserResponse<{
    running: boolean;
    viewport: string;
    theme: string;
    mode: string;
    devtools: boolean;
  }>
> {
  try {
    const manager = getBrowserManager();

    const contextConfig: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    const launchConfig = {
      mode: input.mode || 'headed',
      devtools: input.devtools !== undefined ? input.devtools : false, // 默认不开启DevTools
      maximized: input.maximized !== undefined ? input.maximized : false,
    };

    await manager.start(launchConfig);

    // 创建默认页面和上下文
    await manager.getPage(contextConfig);

    logger.info(
      `Browser debug started: ${contextConfig.viewport} ${contextConfig.theme} ${launchConfig.mode} mode`
    );

    return createSuccessResponse(
      {
        running: manager.isRunning(),
        viewport: contextConfig.viewport,
        theme: contextConfig.theme,
        mode: launchConfig.mode,
        devtools: launchConfig.devtools,
      },
      `Browser debug service started successfully in ${launchConfig.mode} mode`
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to start browser debug service');
  }
}

/**
 * 获取浏览器状态
 */
export async function getBrowserStatus(): Promise<
  BrowserResponse<{
    running: boolean;
    contexts: number;
    mode: string;
    devtools: boolean;
    maximized: boolean;
  }>
> {
  try {
    const manager = getBrowserManager();
    const modeInfo = manager.getBrowserMode();

    return createSuccessResponse(
      {
        running: manager.isRunning(),
        contexts: (manager as any).contexts?.size || 0, // 访问私有属性，仅用于状态检查
        mode: modeInfo.mode || 'headed',
        devtools: modeInfo.devtools || false,
        maximized: modeInfo.maximized || false,
      },
      'Browser status retrieved successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to get browser status');
  }
}

/**
 * 重启浏览器
 */
export async function restartBrowser(): Promise<BrowserResponse<{ running: boolean }>> {
  try {
    const manager = getBrowserManager();
    await manager.restart();

    logger.info('Browser restarted');

    return createSuccessResponse(
      {
        running: manager.isRunning(),
      },
      'Browser restarted successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to restart browser');
  }
}

/**
 * 导航到指定URL
 */
export async function navigateToUrl(input: {
  url: string;
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
  waitForLoad?: boolean;
}): Promise<BrowserResponse<{ url: string; title: string }>> {
  try {
    const manager = getBrowserManager();

    const config: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    await manager.navigate(config, input.url);

    // 等待页面加载完成
    if (input.waitForLoad !== false) {
      await manager.waitFor(config, 'networkidle');
    }

    const page = await manager.getPage(config);
    const title = await page.title();

    logger.info(`Navigated to: ${input.url}`);

    return createSuccessResponse(
      {
        url: input.url,
        title,
      },
      `Successfully navigated to ${input.url}`
    );
  } catch (error) {
    return createErrorResponse(error, `Failed to navigate to ${input.url}`);
  }
}

/**
 * 截图
 */
export async function takeScreenshot(input: {
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
  type?: 'viewport' | 'fullpage';
  selector?: string;
  waitMs?: number;
  quality?: number;
  filename?: string;
}): Promise<
  BrowserResponse<{
    filePath: string;
    size: number;
    dimensions?: { width: number; height: number };
  }>
> {
  try {
    const manager = getBrowserManager();

    const config: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    const options: ScreenshotOptions = {
      type: input.type || 'viewport',
      selector: input.selector,
      waitMs: input.waitMs || 1000, // 默认等待1秒让页面稳定
      quality: input.quality,
      path: input.filename, // 如果提供了filename，使用它
    };

    const filePath = await manager.screenshot(config, options);

    // 获取文件信息
    const stats = await fs.stat(filePath);

    logger.info(`Screenshot taken: ${filePath} (${stats.size} bytes)`);

    return createSuccessResponse(
      {
        filePath,
        size: stats.size,
      },
      `Screenshot saved successfully: ${filePath}`
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to take screenshot');
  }
}

/**
 * 获取页面信息（使用真正的活跃页面）
 */
export async function getPageInfo(
  input: {
    viewport?: 'desktop' | 'tablet' | 'mobile';
    theme?: 'light' | 'dark';
    useActiveTab?: boolean;
  } = {}
): Promise<
  BrowserResponse<{
    url: string;
    title: string;
    loadTime: number;
    domNodes: number;
    networkRequests: number;
    viewport: { width: number; height: number };
    userAgent: string;
    isActiveTab?: boolean;
    lastActiveTime?: number;
  }>
> {
  try {
    const manager = getBrowserManager();

    // 默认使用活跃页面，除非明确指定了视口配置
    const useActiveTab = input.useActiveTab !== false && !input.viewport && !input.theme;

    let info;
    let page;

    if (useActiveTab) {
      // 使用真正的活跃页面
      info = await manager.getPageInfo({
        viewport: 'desktop',
        theme: 'light',
        useActiveTab: true,
      });
      page = manager.getCurrentActiveTab();

      if (!page) {
        throw new Error('No active page found');
      }
    } else {
      // 使用配置指定的页面
      const config: BrowserContextConfig = {
        viewport: input.viewport || 'desktop',
        theme: input.theme || 'light',
      };

      info = await manager.getPageInfo(config);
      page = await manager.getPage(config);
    }

    // 获取视口大小和用户代理
    const viewport = page.viewportSize() || { width: 0, height: 0 };
    const userAgent = await page.evaluate(() => navigator.userAgent);

    logger.info(
      `Page info retrieved: ${info.title} (${info.url})${info.isActiveTab ? ' [ACTIVE TAB]' : ''}`
    );

    return createSuccessResponse(
      {
        ...info,
        viewport,
        userAgent,
      },
      `Page information retrieved successfully${info.isActiveTab ? ' from active tab' : ''}`
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to get page information');
  }
}

/**
 * 执行JavaScript代码
 */
export async function executeScript(input: {
  script: string;
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
  timeout?: number;
}): Promise<BrowserResponse<{ result: any; executionTime: number }>> {
  try {
    const manager = getBrowserManager();

    const config: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    const startTime = Date.now();
    const result = await manager.evaluateScript(config, input.script);
    const executionTime = Date.now() - startTime;

    logger.info(`Script executed in ${executionTime}ms`);

    return createSuccessResponse(
      {
        result,
        executionTime,
      },
      `JavaScript executed successfully in ${executionTime}ms`
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to execute JavaScript');
  }
}

/**
 * 注入CSS样式
 */
export async function injectCSS(input: {
  css: string;
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
}): Promise<BrowserResponse<{ injected: boolean }>> {
  try {
    const manager = getBrowserManager();

    const config: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    await manager.injectCSS(config, input.css);

    logger.info('CSS injected successfully');

    return createSuccessResponse(
      {
        injected: true,
      },
      'CSS styles injected successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to inject CSS');
  }
}

/**
 * 等待元素或页面状态
 */
export async function waitForElement(input: {
  selector: string;
  viewport?: 'desktop' | 'tablet' | 'mobile';
  theme?: 'light' | 'dark';
  timeout?: number;
  state?: 'visible' | 'hidden' | 'attached' | 'detached';
}): Promise<BrowserResponse<{ found: boolean; waitTime: number }>> {
  try {
    const manager = getBrowserManager();

    const config: BrowserContextConfig = {
      viewport: input.viewport || 'desktop',
      theme: input.theme || 'light',
    };

    const startTime = Date.now();
    await manager.waitForElement(config, input.selector, {
      state: input.state || 'visible',
      timeout: input.timeout || 10000,
    });
    const waitTime = Date.now() - startTime;

    logger.info(
      `Element found after ${waitTime}ms: ${input.selector} (state: ${input.state || 'visible'})`
    );

    return createSuccessResponse(
      {
        found: true,
        waitTime,
      },
      `Element found: ${input.selector}`
    );
  } catch (error) {
    return createErrorResponse(error, `Failed to find element: ${input.selector}`);
  }
}

/**
 * 设置代理服务器
 */
export async function setProxy(input: {
  server: string; // e.g. "http://127.0.0.1:7890" or "socks5://127.0.0.1:1080"
  username?: string;
  password?: string;
  bypass?: string; // e.g. "localhost,127.0.0.1,*.local"
}): Promise<
  BrowserResponse<{ enabled: boolean; server: string; bypass?: string; restartRequired?: boolean }>
> {
  try {
    const manager = getBrowserManager();

    // 检查浏览器是否正在运行，如果是则需要重启
    const wasRunning = manager.isRunning();

    await manager.setProxy({
      server: input.server,
      username: input.username,
      password: input.password,
      bypass: input.bypass,
    });

    logger.info(`Proxy set: ${input.server}`);

    return createSuccessResponse(
      {
        enabled: true,
        server: input.server,
        bypass: input.bypass,
        restartRequired: wasRunning, // 如果浏览器正在运行，则需要重启
      },
      `Proxy configured successfully: ${input.server}`
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to set proxy');
  }
}

/**
 * 获取代理状态
 */
export async function getProxyStatus(): Promise<
  BrowserResponse<{
    enabled: boolean;
    server?: string;
    bypass?: string;
    source?: 'api' | 'environment' | 'none';
  }>
> {
  try {
    const manager = getBrowserManager();
    const status = manager.getProxyStatus();

    // 检查代理来源
    let source: 'api' | 'environment' | 'none' = 'none';
    if (status.enabled) {
      const envProxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
      source = envProxy && status.server === envProxy ? 'environment' : 'api';
    }

    return createSuccessResponse(
      {
        ...status,
        source,
      },
      status.enabled ? `Proxy enabled: ${status.server}` : 'Proxy not configured'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to get proxy status');
  }
}

/**
 * 清除代理设置
 */
export async function clearProxy(): Promise<
  BrowserResponse<{
    enabled: boolean;
    restartRequired?: boolean;
  }>
> {
  try {
    const manager = getBrowserManager();

    // 检查浏览器是否正在运行
    const wasRunning = manager.isRunning();
    const hadProxy = manager.getProxyStatus().enabled;

    await manager.clearProxy();

    logger.info('Proxy cleared');

    return createSuccessResponse(
      {
        enabled: false,
        restartRequired: wasRunning && hadProxy, // 如果浏览器正在运行且之前有代理，则需要重启
      },
      'Proxy cleared successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to clear proxy');
  }
}

/**
 * 设置浏览器模式
 */
export async function setBrowserMode(input: {
  mode?: 'headed' | 'headless';
  devtools?: boolean;
  maximized?: boolean;
}): Promise<
  BrowserResponse<{
    mode: string;
    devtools: boolean;
    maximized: boolean;
    changed: boolean;
    restarted: boolean;
  }>
> {
  try {
    const manager = getBrowserManager();

    const previousMode = manager.getBrowserMode();
    const result = await manager.setBrowserMode(input);

    // 检查是否有变化
    const changed = JSON.stringify(previousMode) !== JSON.stringify(result);
    const restarted = manager.isRunning(); // 简化版不跟踪重启状态

    logger.info(`Browser mode updated: ${JSON.stringify(result)}`);

    return createSuccessResponse(
      {
        mode: result.mode || 'headed',
        devtools: result.devtools || false,
        maximized: result.maximized || false,
        changed,
        restarted,
      },
      changed ? 'Browser mode updated successfully' : 'Browser mode unchanged'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to set browser mode');
  }
}

/**
 * 获取浏览器模式
 */
export async function getBrowserMode(): Promise<
  BrowserResponse<{
    mode: string;
    devtools: boolean;
    maximized: boolean;
    running: boolean;
  }>
> {
  try {
    const manager = getBrowserManager();
    const modeInfo = manager.getBrowserMode();

    return createSuccessResponse(
      {
        mode: modeInfo.mode || 'headed',
        devtools: modeInfo.devtools || false,
        maximized: modeInfo.maximized || false,
        running: manager.isRunning(), // 使用 isRunning() 方法
      },
      'Browser mode retrieved successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to get browser mode');
  }
}

/**
 * 关闭浏览器
 */
export async function closeBrowser(): Promise<BrowserResponse<{ closed: boolean }>> {
  try {
    const manager = getBrowserManager();
    await manager.close();

    logger.info('Browser closed');

    return createSuccessResponse(
      {
        closed: true,
      },
      'Browser closed successfully'
    );
  } catch (error) {
    return createErrorResponse(error, 'Failed to close browser');
  }
}

// 导出所有工具函数
export const browserDebugTools = {
  start_browser_debug: startBrowserDebug,
  get_browser_status: getBrowserStatus,
  restart_browser: restartBrowser,
  navigate_to_url: navigateToUrl,
  take_screenshot: takeScreenshot,
  get_page_info: getPageInfo,
  execute_script: executeScript,
  inject_css: injectCSS,
  wait_for_element: waitForElement,
  set_proxy: setProxy,
  get_proxy_status: getProxyStatus,
  clear_proxy: clearProxy,
  set_browser_mode: setBrowserMode,
  get_browser_mode: getBrowserMode,
  close_browser: closeBrowser,
};

// 导出工具包定义供自动发现注册
export { browserDebugToolPackage } from './tool.js';

// 默认导出工具包（用于自动发现系统）
import { browserDebugToolPackage } from './tool.js';
export default browserDebugToolPackage;
